﻿using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Utilities.TokenModels;

namespace Api
{
    [Route("")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        private readonly IUserLogic _userLogic;
        private readonly IRefreshTokenLogic _refreshTokenLogic;
        private readonly ISuperUserLogic _superUserLogic;
        private readonly ILoginUserDataPermission _loginUserDataPermission;

        public AuthController(IConfiguration configuration, IUserLogic userLogic, IRefreshTokenLogic refreshTokenLogic, ISuperUserLogic superUserLogic, ILoginUserDataPermission loginUserDataPermission)
        {
            _configuration = configuration;
            _userLogic = userLogic;
            _refreshTokenLogic = refreshTokenLogic;
            _superUserLogic = superUserLogic;
            _loginUserDataPermission = loginUserDataPermission;
        }

        [Route("token")]
        [HttpPost]
        public Task<TokenModel> Token(LoginModel model, [FromHeader] string clientID)
        {
            if (clientID.IsEmpty())
            {
                throw new CustomException("客户端标识不可为空！");
            }

            if (model.LoginCode.IsEmpty() || model.LoginName.IsEmpty() || model.Password.IsEmpty())
            {
                throw new CustomException("用户代码、用户名、密码均不可为空！");
            }

            UserModel user = null;
            //(bool, List<int>) userRoleDepartment = default;
            //(bool, List<int>) userKuangShanDepartment = default;
            //List<int> userWarehouseIDs = default;
            //List<int> userWarehouseIDsWithDataDepartment = default;
            //List<int> regulatorDepartmentIDs = default;

            if (model.LoginCode == "SupLogin")
            {
                //超级用户登录
                user = _superUserLogic.GetUserByLogin(model.LoginName, model.Password);
                //userRoleDepartment = (false, null);
                //userKuangShanDepartment = (false, null);
            }
            else
            {
                //集团用户或监管用户登录

                //验证用户是否存在，且密码是否正确，如果验证成功，就获取用户信息
                user = _userLogic.GetUserByLogin(model.LoginCode, model.LoginName, model.Password);

                //获取用户所有角色中所有部门ID的集合
                if (user.LoginUserType == LoginUserType.集团)
                {
                    //userRoleDepartment = _loginUserDataPermission.GetUserRoleDepartmentInfo(user.UserID);
                    //userKuangShanDepartment = _loginUserDataPermission.GetUserKuangShanDepartmentInfo(user.UserID);
                    //userWarehouseIDs = _loginUserDataPermission.GetUserWarehouseIDs(user.UserID);
                    //userWarehouseIDsWithDataDepartment = _loginUserDataPermission.GetUserWarehouseIDsByDataDepartment(user.LoginTypeID, userRoleDepartment.Item1, userRoleDepartment.Item2);
                }
                else if (user.LoginUserType == LoginUserType.监管部门)
                {
                    //regulatorDepartmentIDs = _loginUserDataPermission.GetRegulatorDepartmentIDs(user.UserID);
                }
                else
                {
                    throw new CustomException("登录时获取身份信息异常！");
                }
            }


            //2.生成JWT
            //Header,选择签名算法
            var signingAlogorithm = SecurityAlgorithms.HmacSha256;

            //Payload,存放用户信息，下面我们放了一个用户id
            var claims = new[]
            {
                //登录身份信息
                new Claim(Gx._LOGIN_CODE_KEY,model.LoginCode),
                new Claim(Gx._LOGIN_USER_TYPE_KEY,((int)user.LoginUserType).ToString()),
                new Claim(Gx._LOGIN_TYPE_ID_KEY,user.LoginTypeID.ToString()),

                //用户信息
                new Claim(Gx._USERID_KEY,user.UserID.ToString()),
                new Claim(Gx._USERNAME_KEY,user.Name),

                //扩展权限相关信息
                //new Claim(Gx._LOGIN_USER_ROLE_DEPARTMENT_KEY,userRoleDepartment.Serialize()),
                //new Claim(Gx._LOGIN_USER_KUANG_SHAN_DEPARTMENT_KEY,userKuangShanDepartment.Serialize()),
                //new Claim(Gx._LOGIN_USER_WAREHOUSE_IDS_KEY,userWarehouseIDs.Serialize()),
                //new Claim(Gx._LOGIN_USER_WAREHOUSE_IDS_WITH_DATA_DEPARTMENT_KEY,userWarehouseIDsWithDataDepartment.Serialize()),
                //new Claim(Gx._LOGIN_REGULATOR_DEPARTMENT_IDS_KEY,regulatorDepartmentIDs.Serialize())
            };

            var issuedDate = DateTime.UtcNow;
            var expiresDate = issuedDate.AddHours(AppSetting.Auth.ExpireHour);

            //Signature
            //取出私钥并以utf8编码字节输出
            var secretByte = Encoding.UTF8.GetBytes(AppSetting.Auth.SecretKey);
            //使用非对称算法对私钥进行加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            //使用HmacSha256来验证加密后的私钥生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, signingAlogorithm);
            //生成Token
            var Token = new JwtSecurityToken(
                    //发布者
                    issuer: AppSetting.Auth.Issuer,
                    //接收者
                    audience: AppSetting.Auth.Audience,
                    //存放的用户信息
                    claims: claims,
                    //发布时间
                    notBefore: issuedDate,
                    //有效期
                    expires: expiresDate,
                    //数字签名
                    signingCredentials: signingCredentials
                );

            //生成字符串token
            var TokenStr = new JwtSecurityTokenHandler().WriteToken(Token);

            //在这里处理把数据添加到RefreshToken表中
            _refreshTokenLogic.Insert(new RefreshTokenModel
            {
                UserID = user.UserID,
                LoginCode = model.LoginCode,
                LoginType = (int)user.LoginUserType,
                LoginTypeID = user.LoginTypeID,
                TokenValue = Gx.MD5(TokenStr),
                IssuedOn = issuedDate,
                ExpiredOn = expiresDate,
            });

            return Task.FromResult(new TokenModel
            {
                Access_token = TokenStr,
                Refresh_token = Guid.NewGuid().ToString("N")
            });
        }

        //[HttpPost]
        //public Task<TokenModel> RefreshToken(RefreshModel model)
        //{
        //    //TODO:在这个方法里还要处理一下，通过RefreshToken表中取到相应数据，并来验证token过期的问题

        //    var secretByte = Encoding.UTF8.GetBytes(AppSetting.Auth.SecretKey);
        //    var secKey = new SymmetricSecurityKey(secretByte);

        //    var tokenHandler = new JwtSecurityTokenHandler();
        //    SecurityToken validatedToken;

        //    tokenHandler.ValidateToken(model.Token, new TokenValidationParameters()
        //    {
        //        ValidateIssuerSigningKey = true,
        //        IssuerSigningKey = secKey,
        //        ValidateIssuer = true,
        //        ValidIssuer = AppSetting.Auth.Issuer,
        //        ValidateAudience = true,
        //        ValidAudience = AppSetting.Auth.Audience,
        //        ValidateLifetime = false
        //    }, out validatedToken);

        //    var jwtToken = validatedToken as JwtSecurityToken;

        //    if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
        //    {
        //        throw new CustomException("Token不合法！");
        //    }


        //    //通过上面的jwtToken获取到原本的Claim数据
        //    var clientID = jwtToken.Claims.FirstOrDefault(x => x.Type == Gx._CLIENTID_KEY).Value;
        //    var userID = jwtToken.Claims.FirstOrDefault(x => x.Type == Gx._USERID_KEY).Value;
        //    var name = jwtToken.Claims.FirstOrDefault(x => x.Type == Gx._USERNAME_KEY).Value;

        //    //Payload,存放用户信息，下面我们放了一个用户id
        //    //TODO:下面的信息应该是直接从上面的jwtToken中获取
        //    var claims = new[]
        //    {
        //        new Claim(Gx._CLIENTID_KEY,clientID),
        //        new Claim(Gx._USERID_KEY,userID),
        //        new Claim(Gx._USERNAME_KEY,name)
        //    };

        //    var issuedDate = DateTime.UtcNow;
        //    var expiresDate = issuedDate.AddHours(AppSetting.Auth.ExpireHour);

        //    var signingAlogorithm = SecurityAlgorithms.HmacSha256;
        //    //使用非对称算法对私钥进行加密
        //    var signingKey = new SymmetricSecurityKey(secretByte);
        //    //使用HmacSha256来验证加密后的私钥生成数字签名
        //    var signingCredentials = new SigningCredentials(signingKey, signingAlogorithm);
        //    //生成Token

        //    var Token = new JwtSecurityToken(
        //            //发布者
        //            issuer: AppSetting.Auth.Issuer,
        //            //接收者
        //            audience: AppSetting.Auth.Audience,
        //            //存放的用户信息
        //            claims: claims,
        //            //发布时间
        //            notBefore: issuedDate,
        //            //有效期
        //            expires: expiresDate,
        //            //数字签名
        //            signingCredentials: signingCredentials
        //        );


        //    //生成字符串token
        //    var TokenStr = new JwtSecurityTokenHandler().WriteToken(Token);

        //    //在这里处理把数据添加到RefreshToken表中
        //    _refreshTokenLogic.Insert(new RefreshTokenModel
        //    {
        //        UserID = userID.ToInt(),
        //        ClientID = clientID,
        //        TokenValue = Gx.MD5(TokenStr),
        //        IssuedOn = issuedDate,
        //        ExpiredOn = expiresDate,
        //    });

        //    return Task.FromResult(new TokenModel
        //    {
        //        Access_token = TokenStr,
        //        Refresh_token = Guid.NewGuid().ToString("N")
        //    });
        //}
    }
}
